{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "a3b6270b-424d-4ea3-bbf6-c3d3ed118d7a",
   "metadata": {},
   "source": [
    "# Exercise Set 2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6db295a8-7128-40a9-9bf1-096c60f4bc1b",
   "metadata": {},
   "source": [
    "### True or False"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5542c846-91d6-419b-b360-a4be51a89305",
   "metadata": {},
   "source": [
    "**Q1.** Suppose the solar forecast for the week totaled more energy than the total demand. In this case it's guaranteed that no energy will be bought from the grid.\n",
    "- True\n",
    "- `False`"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f6934b39-c3d2-4595-ac2b-03dcce6fab8f",
   "metadata": {},
   "source": [
    "### Formualtion and Coding"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "55ba277f-b582-4162-9ed7-1758a6864116",
   "metadata": {},
   "outputs": [],
   "source": [
    "%pip install gurobipy\n",
    "\n",
    "import gurobipy as gp\n",
    "from gurobipy import GRB\n",
    "\n",
    "batteries = [\"Battery0\", \"Battery1\"]\n",
    "time_periods = range(180)\n",
    "capacity = {\"Battery0\": 60, \"Battery1\": 80} \n",
    "p_loss = {\"Battery0\": 0.95, \"Battery1\": 0.9} \n",
    "initial = {\"Battery0\": 20, \"Battery1\": 30} \n",
    "\n",
    "m = gp.Model() \n",
    "\n",
    "# flow_in = m.addVars(batteries, time_periods, name=\"flow_in\") \n",
    "# flow_out = m.addVars(batteries, time_periods, name=\"flow_out\")\n",
    "# grid = m.addVars(time_periods, name=\"grid\")\n",
    "# state = m.addVars(batteries, time_periods, name=\"state\") \n",
    "# gen = m.addVars(time_periods, name=\"gen\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6e39bd75-d9ce-453f-ac69-6a2f7c498890",
   "metadata": {},
   "source": [
    "Feel free to use the commented code above to copy and paste."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3defaedc-5960-40f7-b830-e387cb9b3c6b",
   "metadata": {},
   "source": [
    "**Q2.** Write a line of code that sets the objective coefficients for the energy storage problem (minimizing grid electricity purchased) using the `addVars()` command. Check your code by writing to a file named `model.lp` "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c3c678e2-6f38-49f5-aa61-cfadbbd3130f",
   "metadata": {},
   "outputs": [],
   "source": [
    "#### gurobipy code\n",
    "grid = m.addVars(time_periods, obj = 1, name=\"grid\")\n",
    "m.write('model.lp')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5836149c-060a-4d03-89fa-16154b714be6",
   "metadata": {},
   "source": [
    "**Q3.** [Depth of discharge](https://en.wikipedia.org/wiki/Depth_of_discharge) refers to the percentage a battery's level is below its capacity. To help maintain the batteries, a restriction is put into place that says the depth of discharge for **both batteries combined** cannot exceed 70% of the **total capacity**. Formulate constraints (write the inequalities algebraically) that model this and write code in gurobypi.\n",
    "\n",
    "**Hints:** Make sure your generator expression is in parenthesis if you get an error and consider the initial state a few cells above."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cb8a761f-b5fb-447f-9be5-fb1d6130b9ad",
   "metadata": {},
   "source": [
    "Formulation:\n",
    "$$\n",
    "\\begin{align*}\n",
    "\\sum_bs_{b,t} \\ge (1-0.7)*\\sum_bc_b, \\quad \\forall t \\in T\n",
    "\\end{align*}\n",
    "$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1e9d4938-aad8-4653-b5b8-cfa14b8e4ae9",
   "metadata": {},
   "outputs": [],
   "source": [
    "#### gurobipy code\n",
    "state = m.addVars(batteries, time_periods, name=\"state\") \n",
    "depth_of_discharge = m.addConstrs((gp.quicksum(state[b,t] for b in batteries) >= 0.3*sum(capacity[b] for b in batteries) for t in time_periods), name = 'depth_restriction')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c868cddd-fd51-4dac-8783-ca4ef8ab6fae",
   "metadata": {},
   "source": [
    "**Q4.** At the start of each day (other than the first) it is required that each battery be at least 40% full. The time periods for the start of each day are 30, 60, 90, 120, and 150. Formulate these constraints and write gurpbipy code. Do not worry about the solar forecast nor the contrstaint in **Q3**."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "194cfcbc-359c-4b32-b2fc-4b54ccdd303f",
   "metadata": {},
   "source": [
    "Formulation:\n",
    "$$\n",
    "\\begin{align*}\n",
    "s_{b,t} \\ge 0.4*c_b, \\quad \\forall t \\in [30,60,90,120,150]\n",
    "\\end{align*}\n",
    "$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "616de220-f53b-460c-b098-2e02d21fc273",
   "metadata": {},
   "outputs": [],
   "source": [
    "#### gurobipy code\n",
    "m = gp.Model() # define the model again to make sure it is reset\n",
    "state = m.addVars(batteries, time_periods, name=\"state\") \n",
    "start_of_day = m.addConstrs((state[b,t] >= 0.4*capacity[b] for b in batteries for t in [30,60,90,120,150]), name = 'start_of_day') #in time_periods if t"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c30485e8-6883-4f3c-9220-a6650e793f8b",
   "metadata": {},
   "source": [
    "### Modeling with Binary Variables\n",
    "\n",
    "You have five light bulbs. Let $y_i = 1$ if lighbulb $i$ is on and $y_i = 0$ if it is off, for$\\space i \\in \\{1,2,3,4,5\\}$. Model the following statements using binary variables and $\\le,\\space\\ge,\\space=$. All questions are independent of each other. "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8500fa22-9536-4266-a80b-f9e677171d29",
   "metadata": {},
   "source": [
    "**Q4.** No more than three of the lightbulbs can be on.\n",
    "$$\n",
    "\\begin{align*}\n",
    "\\sum_i y_i \\le 3\n",
    "\\end{align*}\n",
    "$$"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fd67c59e-fd98-4f63-9a49-d3c91302332b",
   "metadata": {},
   "source": [
    "**Q5.** Lightbulb 2 or ligthbulb 3 must be on.\n",
    "$$\n",
    "\\begin{align*}\n",
    "y_2 + y_3 \\ge 1\n",
    "\\end{align*}\n",
    "$$"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "84ba908d-ca27-4278-be80-3b0d86d0d862",
   "metadata": {},
   "source": [
    "**Q6.** If lightbulb 1 is on, then lightbulb 5 is also on. \n",
    "$$\n",
    "\\begin{align*} \n",
    "y_1 \\le y_5\n",
    "\\end{align*}\n",
    "$$"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "85ffcb81-53bf-4d3f-85c0-ae14dbc34664",
   "metadata": {},
   "source": [
    "**Q7.** If lightbulb 1 is off, then lightbulb 3 is on. \n",
    "$$\n",
    "\\begin{align*} \n",
    "1-y_1 \\le y_3\n",
    "\\end{align*}\n",
    "$$"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "82b39e21-c89f-4bbc-9498-0522dff56141",
   "metadata": {},
   "source": [
    "**Q8.** If lightbulb 1 is off, then lightbulb 2 is off. \n",
    "$$\n",
    "\\begin{align*} \n",
    "1-y_1 &\\le 1-y_2 \\\\\n",
    "y_1 &\\ge y_2\n",
    "\\end{align*}\n",
    "$$"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "043015c9-68d3-4e7a-af5d-7d2a87f28c2c",
   "metadata": {},
   "source": [
    "**Q9.** Lightbulb 2 and lightbulb 4 are in opposite on/off states.\n",
    "$$\n",
    "\\begin{align*} \n",
    "y_2 =& 1-y_4 \\\\\n",
    "y_2 + y_4 =& 1\n",
    "\\end{align*}\n",
    "$$"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1e7396d3-cbc4-416d-be28-95a07e3c243a",
   "metadata": {},
   "source": [
    "**Q10.** If any of lightbulbs 1 through 4 are on, then lighbtulb 5 is also on. \n",
    "$$\n",
    "\\begin{align*}\n",
    "y_1 + y_2 + y_3 + y_4 \\le 4y_5\n",
    "\\end{align*}\n",
    "$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d271c17f-ea69-4523-87a4-e2a407d51700",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  },
  "toc-autonumbering": false,
  "toc-showcode": false,
  "toc-showmarkdowntxt": false
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
